package cn.com.acca.ma.service.impl;

import java.awt.Color;
import java.awt.Paint;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.common.util.StringUtil;
import cn.com.acca.ma.model.StockIndexWeekend;
import cn.com.acca.ma.service.StockIndexWeekendService;

public class StockIndexWeekendServiceImpl extends BaseServiceImpl<StockIndexWeekendServiceImpl, StockIndexWeekend> implements StockIndexWeekendService {
	/******************************************** 更新每周的数据 ********************************************************/
	/**
	 * 根据日期，更新STOCK_INDEX_WEEKEND表的基础数据
	 */
	public void writeStockIndexWeekendByDate(){
		String stockIndexWeekendBeginDate = PropertiesUtil.getValue(STOCK_INDEX_WEEKEND_PROPERTIES,"stockIndexWeekend.time.begin_date");
		String stockIndexWeekendEndDate = PropertiesUtil.getValue(STOCK_INDEX_WEEKEND_PROPERTIES,"stockIndexWeekend.time.end_date");
	
		stockIndexWeekendDao.writeStockIndexWeekendByDate(stockIndexWeekendBeginDate,stockIndexWeekendEndDate);
	}
	
	/**
	 * 根据日期，更新STOCK_INDEX_WEEKEND表的Hei Kin Ashi数据
	 */
	public void writeStockIndexWeekendHeiKinAshiByDate(){
		String stockIndexWeekendBeginDate = PropertiesUtil.getValue(STOCK_INDEX_WEEKEND_PROPERTIES,"stockIndexWeekend.heiKinAshi.begin_date");
		String stockIndexWeekendEndDate = PropertiesUtil.getValue(STOCK_INDEX_WEEKEND_PROPERTIES,"stockIndexWeekend.heiKinAshi.end_date");
	
		stockIndexWeekendDao.writeStockIndexWeekendHeiKinAshiByDate(stockIndexWeekendBeginDate,stockIndexWeekendEndDate);
	}
	
	/********************************************* 更新每周的图片 ******************************************************/
	/**
	 * 创建StockIndexWeekend对象的Hei Kin Ashi图片
	 */
	@SuppressWarnings({ "deprecation", "static-access" })
	public void createStockIndexWeekendHeiKinAshiPicture() {
		String stockIndexWeekendBeginDate = PropertiesUtil.getValue(STOCK_INDEX_WEEK_PICTURE_PROPERTIES,"stockIndexWeekPicture.beginDate");
		String stockIndexWeekendEndDate = PropertiesUtil.getValue(STOCK_INDEX_WEEK_PICTURE_PROPERTIES,"stockIndexWeekPicture.endDate");
		String stockIndexWeekendTimeInterval = PropertiesUtil.getValue(STOCK_INDEX_WEEK_PICTURE_PROPERTIES, "stockIndexWeekPicture.timeInterval");
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
		double kLineMaxValue = Double.MIN_VALUE;// 设置K线数据当中的最大值
		double kLineMinValue = Double.MAX_VALUE;// 设置K线数据当中的最小值
		double amountMaxValue = Double.MIN_VALUE;// 设置成交量的最大值
		double amountMinValue = Double.MAX_VALUE;// 设置成交量的最低值
		
		List<StockIndexWeekend> stockIndexWeekendList=stockIndexWeekendDao.getDataForLineChart(stockIndexWeekendBeginDate, stockIndexWeekendEndDate, "sh000001");
		if(0==stockIndexWeekendList.size()){
			return;
		}
		
		// 获取日期，开盘价，最高价，最低价和收盘价
		OHLCSeries seriesPrice = new OHLCSeries("平均K线图（Hei Kin Ashi）");// 高开低收数据序列，上证指数平均K线图的四个数据，依次是开，高，低，收
		seriesPrice.clear();
		for (int i = 0; i < stockIndexWeekendList.size(); i++) {
			seriesPrice.add(new Day(DateUtil.getDateFromDate(stockIndexWeekendList.get(i).getIndexEndDate()),
					DateUtil.getMonthFromDate(stockIndexWeekendList.get(i).getIndexEndDate()),
					DateUtil.getYearFromDate(stockIndexWeekendList.get(i).getIndexEndDate())),
					stockIndexWeekendList.get(i).getHaIndexOpen().doubleValue(),
					stockIndexWeekendList.get(i).getHaIndexHigh().doubleValue(),
					stockIndexWeekendList.get(i).getHaIndexLow().doubleValue(),
					stockIndexWeekendList.get(i).getHaIndexClose().doubleValue());
		}
		for(int i=1;i<=100;i++){
			seriesPrice.add(new Day((0+i)%28+1,
					(0+i)%12+1,
					1900+i),
					1000,
					1000,
					1000,
					1000);
		}
		final OHLCSeriesCollection priceSeriesCollection = new OHLCSeriesCollection();//保留平均K线数据的数据集，必须申明为final，后面要在匿名内部类里面用到
		priceSeriesCollection.addSeries(seriesPrice);
		
		// 获取成交量
		TimeSeries seriesAmount=new TimeSeries("");//对应时间成交量数据
		seriesAmount.clear();
		for(int i=0;i<stockIndexWeekendList.size();i++){
			seriesAmount.add(new Day(DateUtil.getDateFromDate(stockIndexWeekendList.get(i).getIndexEndDate()),
					DateUtil.getMonthFromDate(stockIndexWeekendList.get(i).getIndexEndDate()),
					DateUtil.getYearFromDate(stockIndexWeekendList.get(i).getIndexEndDate())),
					stockIndexWeekendList.get(i).getAmount());
		}
		for(int i=1;i<=100;i++){
			seriesAmount.add(new Day((0+i)%28+1,
					(0+i)%12+1,
					1900+i),
					1);
		}
		TimeSeriesCollection amountSeriesCollection=new TimeSeriesCollection();//保留成交量数据的集合
		amountSeriesCollection.addSeries(seriesAmount);
		
		//获取平均K线数据的最高值和最低值
		int seriesCountPrice = priceSeriesCollection.getSeriesCount();//一共有多少个序列，目前为一个
		for (int i = 0; i < seriesCountPrice; i++) {
			int itemCount = priceSeriesCollection.getItemCount(i);//每一个序列有多少个数据项
			for (int j = 0; j < itemCount; j++) {
				if (kLineMaxValue < priceSeriesCollection.getHighValue(i, j)) {//取第i个序列中的第j个数据项的最大值
					kLineMaxValue = priceSeriesCollection.getHighValue(i, j);
				}
				if (kLineMinValue > priceSeriesCollection.getLowValue(i, j)) {//取第i个序列中的第j个数据项的最小值
					kLineMinValue = priceSeriesCollection.getLowValue(i, j);
				}
			}
		}
		
		//获取最高值和最低值
		int seriesCountAmount = amountSeriesCollection.getSeriesCount();//一共有多少个序列，目前为一个
		for (int i = 0; i < seriesCountAmount; i++) {
			int itemCount = amountSeriesCollection.getItemCount(i);//每一个序列有多少个数据项
			for (int j = 0; j < itemCount; j++) {
				if (amountMaxValue < amountSeriesCollection.getYValue(i,j)) {//取第i个序列中的第j个数据项的值
					amountMaxValue = amountSeriesCollection.getYValue(i,j);
				}
				if (amountMinValue > amountSeriesCollection.getYValue(i, j)) {//取第i个序列中的第j个数据项的值
					amountMinValue = amountSeriesCollection.getYValue(i, j);
				}
			}
		}
		
		final CandlestickRenderer candlestickRender=new CandlestickRenderer();//设置平均K线图的画图器，必须申明为final，后面要在匿名内部类里面用到
		candlestickRender.setUseOutlinePaint(true); //设置是否使用自定义的边框线，程序自带的边框线的颜色不符合中国股票市场的习惯
		candlestickRender.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_AVERAGE);//设置如何对平均K线图的宽度进行设定
		candlestickRender.setAutoWidthGap(0.001);//设置各个平均K线图之间的间隔
		candlestickRender.setUpPaint(Color.RED);//设置股票上涨的平均K线图颜色
		candlestickRender.setDownPaint(Color.GREEN);//设置股票下跌的平均K线图颜色
		DateAxis x1Axis=new DateAxis();//设置x轴，也就是时间轴
		x1Axis.setAutoRange(false);//设置不采用自动设置时间范围
		try{
			x1Axis.setRange(dateFormat.parse(StringUtil.convertDateStringByFormat(stockIndexWeekendBeginDate,"-")),dateFormat.parse(StringUtil.convertDateStringByFormat(String.valueOf(Integer.parseInt(stockIndexWeekendTimeInterval)+1), "-")));//设置时间范围，注意时间的最大值要比已有的时间最大值要多一天
		}catch(Exception e){
			e.printStackTrace();
		}
		x1Axis.setTimeline(SegmentedTimeline.newMondayThroughFridayTimeline());//设置时间线显示的规则，用这个方法就摒除掉了周六和周日这些没有交易的日期(很多人都不知道有此方法)，使图形看上去连续
		x1Axis.setAutoTickUnitSelection(false);//设置不采用自动选择刻度值
		x1Axis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);//设置标记的位置
		x1Axis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());//设置标准的时间刻度单位
		x1Axis.setTickUnit(new DateTickUnit(DateTickUnit.DAY,7));//设置时间刻度的间隔，一般以周为单位
		x1Axis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));//设置显示时间的格式
		NumberAxis y1Axis=new NumberAxis();//设定y轴，就是数字轴
		y1Axis.setAutoRange(false);//不使用自动设定范围
		y1Axis.setRange(kLineMinValue*0.9, kLineMaxValue*1.1);//设定y轴值的范围，比最低值要低一些，比最大值要大一些，这样图形看起来会美观些
		y1Axis.setTickUnit(new NumberTickUnit((kLineMaxValue*1.1-kLineMinValue*0.9)/10));//设置刻度显示的密度
		XYPlot plot1=new XYPlot(priceSeriesCollection,x1Axis,y1Axis,candlestickRender);//设置画图区域对象
	  
		XYBarRenderer xyBarRender=new XYBarRenderer(){
			private static final long serialVersionUID = 1L;//为了避免出现警告消息，特设定此值
			public Paint getItemPaint(int i, int j){//匿名内部类用来处理当日的成交量柱形图的颜色与平均K线图的颜色保持一致
				if(priceSeriesCollection.getCloseValue(i,j)>priceSeriesCollection.getOpenValue(i,j)){//收盘价高于开盘价，股票上涨，选用股票上涨的颜色
					return candlestickRender.getUpPaint();
				}else{
					return candlestickRender.getDownPaint();
				}
			}
		};
		
		xyBarRender.setMargin(0.1);//设置柱形图之间的间隔
		NumberAxis y2Axis=new NumberAxis();//设置Y轴，为数值,后面的设置，参考上面的y轴设置
		y2Axis.setAutoRange(false);
		y2Axis.setRange(amountMinValue*0.9, amountMaxValue*1.1);
		y2Axis.setTickUnit(new NumberTickUnit((amountMaxValue*1.1-amountMinValue*0.9)/4));
		XYPlot plot2=new XYPlot(amountSeriesCollection,null,y2Axis,xyBarRender);//建立第二个画图区域对象，主要此时的x轴设为了null值，因为要与第一个画图区域对象共享x轴
		CombinedDomainXYPlot combineddomainxyplot = new CombinedDomainXYPlot(x1Axis);//建立一个恰当的联合图形区域对象，以x轴为共享轴
		combineddomainxyplot.add(plot1, 2);//添加图形区域对象，后面的数字是计算这个区域对象应该占据多大的区域2/3
	    combineddomainxyplot.add(plot2, 1);//添加图形区域对象，后面的数字是计算这个区域对象应该占据多大的区域1/3
	    combineddomainxyplot.setGap(10);//设置两个图形区域对象之间的间隔空间
	    JFreeChart chart = new JFreeChart(stockIndexWeekendList.get(0).getIndexCode(), JFreeChart.DEFAULT_TITLE_FONT, combineddomainxyplot, false);
	    
	    try {
			FileOutputStream fos = new FileOutputStream(PICTURE_PATH+"stock_index_week_hei_kin_ashi/"+stockIndexWeekendBeginDate+"-"+stockIndexWeekendEndDate+"_"+stockIndexWeekendList.get(0).getIndexCode()+PICTURE_FORMAT);
			// 将统计图标输出成JPG文件
			ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
					1, // JPEG图片的质量，0~1之间
					chart, // 统计图标对象
					this.imageWidth, // 宽
					this.IMAGE_HEIGHT, // 高
					null // ChartRenderingInfo 信息
					);
			fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void writeStockIndexWeekend() {

	}


	/******************************************** 更新全部的数据 *****************************************************/
	/**
	 * 更新STOCK_INDEX_WEEK表的基础数据
	 */
	public void writeStockIndexWeek(){
		stockIndexWeekDao.writeStockIndexWeek();
	}
	
	/**
	 * 更新STOCK_INDEX_WEEK表的Hei Kin Ashi数据
	 */
	public void writeStockIndexWeekHeiKinAshi(){
		stockIndexWeekDao.writeStockIndexWeekHeiKinAshi();
	}

	@Override
	public String listToString(List list) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public double averageCloseAfterAdjust(double original, double max, double min) {
		// TODO Auto-generated method stub
		return 0;
	}

	public double adjustData(double maxClose, double minClose, double maxDifDea, double minDifDea, double currentClose) {
		// TODO Auto-generated method stub
		return 0;
	}
}
